package com.woniuxy.creditsystem.systemmag.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniuxy.creditsystem.annos.MyLog;
import com.woniuxy.creditsystem.common.bean.*;
import com.woniuxy.creditsystem.common.mapper.DownloadMapper;
import com.woniuxy.creditsystem.common.mapper.RoleMapper;
import com.woniuxy.creditsystem.systemmag.service.IDownloadService;
import com.woniuxy.creditsystem.systemmag.service.IRoleService;
import com.woniuxy.creditsystem.systemmag.service.ISystemLogService;
import com.woniuxy.creditsystem.systemmag.service.IUserService;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 下载中心的的增、查
 * @author hejie
 */
@Service
@Transactional(readOnly = true)
public class DownloadServiceImpl implements IDownloadService {

    @Resource
    private DownloadMapper downloadMapper;

    @Autowired
    @Lazy
    private IUserService userServiceImpl;
    @Autowired
    @Lazy
    private IRoleService roleServiceImpl;
    @Autowired
    @Lazy
    private ISystemLogService systemLogServiceImpl;
    @Autowired
    @Lazy
    private IDownloadService downloadServiceImpl;

    //从application.properties中获取poi的excel文件存放路径
    @Value("${poiFilePath}")
    private String poiFilePath;

    /**
     * 保存excel文件信息到download_info：把导出的 excel文件信息 保存到download_info中，便于后面在“下载中心”下载
     * @param downloadInfo
     * @return
     * @author hejie
     */
    @MyLog(value = "把导出的excel文件信息，保存到download_info表")
    @Transactional(isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    @Override
    public int saveDownloadInfo(DownloadInfo downloadInfo) {
        return downloadMapper.saveDownloadInfo(downloadInfo);
    }

    /**
     * 新增下载：把导出的 excel文件信息 保存到download_info中，便于后面在“下载中心”下载
     * 把 文件名+后缀 放到ResultMsg的data中返回，方便：“新增下载”时，能够直接自动开始下载，而不用费力去“下载中心”点击“下载”
     * @param dataSourceId 数据源（表）的id
     * @param reportName 用户定义的excel文件名字
     * @return
     * @author hejie
     */
    @MyLog(value = "新增下载")
    @Transactional(isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    @Override
    public ResultMsg newDownload(Long dataSourceId,String reportName) throws IOException {

        switch (dataSourceId.toString()){
            //1.账号管理
            case "32":
                //1.查询第一页的数据
                PageInfo<UserInfo> userPages= userServiceImpl.findAllByParams( 1,  10, new UserInfo());
                List<UserInfo> userPagesList = userPages.getList();
                //2.把查询的数据 导出为excel文件
                return userServiceImpl.write2excel(userPagesList,poiFilePath,reportName);
//                break;

            //2.角色管理
            case "33":
                //1.查询第一页的数据
                PageInfo<RoleInfo> rolePages= roleServiceImpl.findAllByParams( 1,  10, new RoleInfo());
                List<RoleInfo> rolePagesList = rolePages.getList();
                //2.把查询的数据 导出为excel文件
                return roleServiceImpl.write2excel(rolePagesList,poiFilePath,reportName);
//                break;

            //3.系统日志
            case "34":
                //1.查询第一页的数据
                PageInfo<SystemLogInfo> systemLogPages= systemLogServiceImpl.findAllByParams( 1,  10, new SystemLogInfo(),null);
                List<SystemLogInfo> systemLogPagesList = systemLogPages.getList();
                //2.把查询的数据 导出为excel文件
                return systemLogServiceImpl.write2excel(systemLogPagesList,poiFilePath,reportName);
//                break;

            //4.下载中心
            case "36":
                //1.查询第一页的数据
                PageInfo<DownloadInfo> downloadPages= downloadServiceImpl.findAllByParams( 1,  10, new DownloadInfo(),null);
                List<DownloadInfo> downloadPagesList = downloadPages.getList();
                //2.把查询的数据 导出为excel文件
                return downloadServiceImpl.write2excel(downloadPagesList,poiFilePath,reportName);
//                break;
        }
        return null;
    }

    /**
     * 分页查询（同时具有 模糊查询功能--动态sql）
     *
     * @param downloadInfo 查询条件
     * @return
     * @author hejie
     */
//    @MyLog(value = "对角色表分页查询")
    @Override
    public PageInfo<DownloadInfo> findAllByParams(int pageNum, int pageSize, DownloadInfo downloadInfo, String createTimeStr) {
        return PageHelper.startPage(pageNum, pageSize).
                doSelectPageInfo(() -> downloadMapper.findAllByParams(downloadInfo, createTimeStr));
    }

    /**
     * 把页面传回来的table数据，写入到excel文件中；  同时把excel文件信息，写入到download_info表中
     * 大家在你的 把查询结果导出为excel文件（xls）方法的末尾调用一下，如第165行：saveExcelInfo2downloadInfo(simpleFileName);
     *
     * @param tableDataJson 前端查询的table数据
     * @param path 设置excel文件的存放路径
     * @param simpleFileNameUserSet 用户自定义excel文件名（如果为空，就程序设置一个文件名）
     * @return
     * @author hejie
     */
    @MyLog(value = "POI，导出下载中心查询结果为excel文件")
    @Transactional(isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)
    public ResultMsg write2excel(List<DownloadInfo> tableDataJson, String path,String simpleFileNameUserSet) throws IOException {
        if (tableDataJson == null) {
            return new ResultMsg(201, "页面表格内容为空，没有数据可以导出！", null);
        }

        //创建表对象，即工作簿对象
        HSSFWorkbook workbook = new HSSFWorkbook();
        //第一个sheet对象demo1
        HSSFSheet sheet = workbook.createSheet("demo1");
        //行对象
        HSSFRow row = sheet.createRow(0);
        //单元格对象
        HSSFCell cell0 = row.createCell(0);
        cell0.setCellValue("报表名称");
        HSSFCell cell1 = row.createCell(1);
        cell1.setCellValue("状态");
        HSSFCell cell2 = row.createCell(2);
        cell2.setCellValue("创建人");
        HSSFCell cell3 = row.createCell(3);
        cell3.setCellValue("创建时间");

        //解决日期显示不正常的问题：给第1行、第2列单元格写入日期
        //用Excel表对象获取CreationHelper对象
        CreationHelper createHelper = workbook.getCreationHelper();
        //用Excel表对象创建CellStyle对象
        CellStyle cellStyle = workbook.createCellStyle();
        //给cellStyle对象设置Date格式
        cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));

        for (int i = 0; i < tableDataJson.size(); i++) {
            //行对象
            HSSFRow r = sheet.createRow(1 + i);
            //单元格对象
            //0.报表名称
            HSSFCell cellReportName = r.createCell(0);
            cellReportName.setCellValue(tableDataJson.get(i).getReportName());
            //1.状态
            HSSFCell cellStatus = r.createCell(1);
            String status = "";
            if (tableDataJson.get(i).getStatus() == 1) {
                status = "成功";
            } else {
                status = "失败";
            }
            cellStatus.setCellValue(status);

            //2.创建人
            HSSFCell cellCreator = r.createCell(2);
            cellCreator.setCellValue(tableDataJson.get(i).getUserInfo().getUserName());

            //3.创建时间
            HSSFCell cellCreateTime = r.createCell(3);
            //设置 “Date”类型的显示格式
            cellCreateTime.setCellStyle(cellStyle);
            cellCreateTime.setCellValue(tableDataJson.get(i).getCreateTime());
        }

        FileOutputStream os = null;

        //fileName是excel文件名字：包含了“.excel”，该路径需要存到的“download_info表”的“file_path”字段
        //不含后缀名“.xls”
        String simpleFileName= "下载中心" + System.currentTimeMillis();
        //如果用户要自己设置文件名字，就要传入非空的名字
        if (simpleFileNameUserSet!=null && !("".equals(simpleFileNameUserSet))){
            simpleFileName=simpleFileNameUserSet;
        }

        String filePathName = path +File.separator + simpleFileName + ".xls";
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        try {
            os = new FileOutputStream(filePathName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //		workbook1.write(os);
        try {
            workbook.write(os);
        } catch (IOException e) {
            e.printStackTrace();
        }
        os.flush();
        os.close();

        //把 文件名+后缀 放到ResultMsg的data中返回，方便：“新增下载”时，能够直接自动开始下载，而不用费力去“下载中心”点击“下载”
        ResultMsg resultMsg = new ResultMsg(200, "页面表格数据已经写入到" + filePathName, simpleFileName + ".xls");

        //把excel文件信息，保存到download_info表：在“下载中心”中展示和下载
        //大家也这样调用：是不含后缀的excel文件名字。  最终得到的文件名是simpleFileName.xls（simpleFileName是变量）
        saveExcelInfo2downloadInfo(simpleFileName);

        return resultMsg;
    }

    /**
     * 把导出的excel信息，存储到download_info表
     * @author hejie
     * @param simpleFileName 是不含后缀的excel文件名字。  最终得到的文件名是simpleFileName.xls（simpleFileName是变量）
     */
    public void saveExcelInfo2downloadInfo(String simpleFileName) {
        //把当前的excel文件信息存储到 download_info中
        //从Session中获得用户
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        UserInfo userBean = (UserInfo) session.getAttribute("user");
        //datesource_info
        DataSourceInfo dataSourceInfo=new DataSourceInfo();
        //在data_source_info中，“下载中心”的id是36
        dataSourceInfo.setId(36L);
        DownloadInfo downloadInfo=  new DownloadInfo(null,simpleFileName,null,userBean,null,dataSourceInfo,simpleFileName + ".xls");
        //把当前“下载中心”记录写入到数据库download_info
        //downloadServiceImpl要private 成员变量方式的装配进去
//        this.saveDownloadInfo(downloadInfo);
        saveDownloadInfo(downloadInfo);
    }
}
